package org.fujene.communicate.deleter;

import java.util.Map.Entry;
import java.util.TreeMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.LinkedBlockingQueue;

import org.fujene.communicate.hash.VirtualContentHash;
import org.fujene.communicate.node.Node;
import org.fujene.communicate.repli.ReplicateCommunicator;

public class DeleterHost implements Runnable{
	private static CopyOnWriteArrayList<Node> nodes;
	private static Node myNode;
	private static int replication;
	private static LinkedBlockingQueue<Long> deleteQueue;

	static{
		deleteQueue = new LinkedBlockingQueue<Long>();
	}

	public DeleterHost(){}

	public static void addToQueue(long ID){
		deleteQueue.add(Long.valueOf(ID));
	}

	public static boolean isEmpty(){
		return deleteQueue.isEmpty();
	}

	public static int residue(){
		return deleteQueue.size();
	}

	public static void property(int repl, Node ownNode, CopyOnWriteArrayList<Node> list){
		replication = repl;
		myNode = ownNode;
		nodes = list;
	}

	@Override
	public void run(){
		long ID = 0;
		while(true){
			try{
				ID = deleteQueue.take().longValue();
			}catch(InterruptedException e1){
				continue;
			}
			long hash = VirtualContentHash.getContentHash(ID);
			TreeMap<Long, Node> hashList = new TreeMap<Long, Node>();
			Entry<Long, Node> currentEntry = null;
			for(Node eachNode: nodes)
				hashList.put(eachNode.getAttributeHash(hash), eachNode);

			for(int i = 0; i < (replication > nodes.size() ? nodes.size() : replication); i++){
				if(currentEntry == null) currentEntry = hashList.ceilingEntry(Long.valueOf(hash));
				else currentEntry = hashList.higherEntry(currentEntry.getKey());
				if(currentEntry == null) currentEntry = hashList.firstEntry();

				if(currentEntry.getValue() != myNode){
					// remote
					ReplicateCommunicator.deleteContent(currentEntry.getValue(), ID);
				}else{
					// local
					DeleterClient.addToQueue(ID);
				}
			}
		}
	}
}
